<template>
  <DetailBox
    :info="detailInfo"
    title="详情"
    :show-box="detailBox.showDetail"
    :show-button="detailBox.showButton"
    :img-button-visible="imgButtonVisible"
    :judge-selected="judgeSelected"
    :history-button-visible="historyButtonVisible"
    @on-click-button="updateSelectedEarthquake(detailBox.quickEarthquakeId)"
    @on-close="detailBox.showDetail=false"
  />
  <el-row class="toolbar">
    <el-popover
      ref="controlVisible"
      v-model:visible="layerControl.visible"
      placement="bottom"
      trigger="click"
      width="170px"
    >
      <template #reference>
        <el-button
          type="default"
          icon="el-icon-menu"
          class=""
        />
      </template>
      <el-select
        v-model="imageryConfig.mapStyle"
        placeholder="请选择"
        class="toolbar-item"
      >
        <el-option
          v-for="item in imageryConfig.options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-plus"
        @click="$refs.predict.predictVisible=true;closeIndex('predict')"
      >
        灾区识别
      </el-button>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-plus"
        @click="$refs.add.addEarthquakeVisible=true;closeIndex('add')"
      >
        添加地震
      </el-button>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-picture"
        @click="$refs.SeismicZones.SeismicZonesVisible=true;closeIndex('SeismicZones')"
      >
        地震带图
      </el-button>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-office-building"
        @click="cameraTo(100.01959853057154,25.626928636003633,565)"
      >
        三维重建
      </el-button>
      <!--      模型微调参数(100.01778853057153,25.625528636003633)-->
      <!--      ENU:25.625528636003633,100.01778853057153-->
      <el-button

        size="small"
        icon="el-icon-search"
        style="margin: 5px"
        @click="$refs.select.earthquakeSelectVisible=true;closeIndex('select') "
      >
        地震列表
      </el-button>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-map-location"
        @click="cameraTo(selectedEarthquakeInfo.longitude,selectedEarthquakeInfo.latitude,100000);closeIndex('');imgDisplayVisible()"
      >
        直达震区
      </el-button>
      <el-button

        size="small"
        style="margin: 5px"
        icon="el-icon-document"
        @click="$refs.estimate.getEarthquakeSituation();closeIndex('estimate')"
      >
        地震评估
      </el-button>
      <el-popover
        v-model:visible="visibleRoad"
        placement="bottom"
        :width="420"
      >
        <template #reference>
          <el-button
            style="margin: 5px"
            icon="el-icon-position"
            size="small"

            @click="visibleRoad = !visibleRoad;closeIndex('')"
          >
            路径规划
          </el-button>
        </template>
        <div>
          <el-radio-group
            v-model="travelWay"
          >
            <el-radio
              label="driving"
              size="small"
              border
            >
              驾车
            </el-radio>
            <el-radio
              label="walking"
              size="small"
              border
            >
              步行
            </el-radio>
            <el-radio
              label="bicycling"
              size="small"
              border
            >
              电动车
            </el-radio>
          </el-radio-group>
        </div>
        <div style="margin-top: 20px">
          <el-button
            type="primary"
            icon="el-icon-magic-stick"
            size="small"
            @click="selectPositionRoad()"
          >
            选取救援点
          </el-button>
          <el-button
            type="primary"
            icon="el-icon-search"
            size="small"
            @click="getPositionRoad()"
          >
            开始路径规划
          </el-button>
          <el-button
            type="danger"
            icon="el-icon-s-release"
            size="small"
            @click="stopPositionRoad()"
          >
            关闭
          </el-button>
        </div>
      </el-popover>
      <el-popover
        v-model:visible="layerVisible"
        :width="700"
      >
        <template #reference>
          <el-button
            style="margin: 5px"
            icon="el-icon-view"
            size="small"
            type="#67C23A"
            @click="closeIndex('')"
          >
            图层控制
          </el-button>
        </template>
        <div>
          <el-checkbox
            v-model="layerControl.showIntensity"
            label="烈度图"
          />
          <el-checkbox
            v-model="layerControl.showEpicenter"
            label="震源"
          />
          <el-checkbox
            v-model="layerControl.showHospital"
            label="显示医院"
          />
          <el-tooltip
            placement="bottom"
            effect="light"
          >
            <template #content>
              默认的物资总量为1000个
            </template>
            <el-checkbox
              v-model="layerControl.showDistribution"
              label="显示救援物资分配"
            />
          </el-tooltip>
          <el-tooltip>
            <template #content>
              地图上面的边界线
            </template>
            <el-checkbox v-model="layerControl.showGeojson">
              边界线
            </el-checkbox>
          </el-tooltip>
          <el-tooltip placement="bottom">
            <el-checkbox v-model="layerVisible">
              显示选项
            </el-checkbox>
            <template #content>
              关闭图层控制窗口
            </template>
          </el-tooltip>
        </div>
      </el-popover>
      <el-popover
        :width="750"
        :visible="suppliesVisible"
      >
        <template #reference>
          <el-button
            style="margin: 5px"
            icon="el-icon-suitcase"
            size="small"
            type="#67C23A"
            @click="suppliesVisible=true;closeIndex('')"
          >
            物资分配
          </el-button>
        </template>
        <div>
          设置物资分配总量:
          <el-input-number
            v-model="DistributionSum"
            :step="100"
            size="small"
            style="margin-top: 10px;"
          />
          设置物资分配地区数量:
          <el-input-number
            v-model="DistrictSum"
            :step="5"
            size="small"
            style="margin-top: 10px;"
            :min="5"
            :max="30"
          />
          <el-button
            type="primary"
            icon="el-icon-success"
            size="small"
            style="margin-top: 10px;margin-left: 20px"
            @click="reGetCalculateWeight();suppliesVisible=false"
          >
            计算
          </el-button>
          <el-button
            type="danger"
            icon="el-icon-s-release"
            size="small"
            style="margin-top: 10px;margin-left: 10px"
            @click="suppliesVisible=false"
          >
            关闭
          </el-button>
        </div>
      </el-popover>
    </el-popover>

    <EarthquakeSelect
      ref="select"
      :selected-earthquake-id="selectedEarthquakeInfo.earthquakeId"
      @change-select="updateSelectedEarthquake"
      @update-list="updateEarthquakePositionInfoList"
      @jump-to="cameraTo"
    />
    <EstimateEarthquake
      ref="estimate"
      :earthquake="selectedEarthquakeInfo"
    />
    <Predict ref="predict" />
    <AddEarthquake ref="add" />
    <ImgDisplay ref="img" />
    <SeismicZones ref="SeismicZones" />
  </el-row>
  <!--    cesium代码-->
  <el-row
    ref="viewerContainer"
    v-loading="cesiumLoading"
    class="viewer"
    element-loading-text="初次加载可能稍慢，请耐心等待"
  >
    <vc-viewer
      ref="vcViewer"
      fill="green"
      :animation="viewerConfig.animation"
      :base-layer-picker="viewerConfig.baseLayerPicker"
      :timeline="viewerConfig.timeline"
      :fullscreen-button="viewerConfig.fullscreenButton"
      :fullscreen-element="viewerConfig.fullscreenElement"
      :info-box="viewerConfig.infoBox"
      :selection-indicator="false"
      :show-credit="viewerConfig.showCredit"
      @ready="onViewerReady"
      @cesium-ready="cesiumReady"
    >
      <CesiumTileset 
        :show="layerControl.showModel"
      />
      <CesiumGeojson
        :show="layerControl.showGeojson"
      />
      <!-- 测绘工具 -->
      <vc-selection-indicator
        ref="selectionIndicator"
        @pick-evt="pickEvt"
      />
      <CesiumMeasurements />
      <CesiumEarthquakePoint
        :earthquake-position-info-list="earthquakePositionInfoList"
        :show="layerControl.showEpicenter"
      />
      <!-- 烈度图 -->
      <CesiumEarthquakeIntensity
        :show="layerControl.showIntensity"
        :selected-earthquake-info="selectedEarthquakeInfo"
      />
      <!--      <vc-terrain-provider-tianditu token="fd7029d3dff756b437af91d68aadc6bf"></vc-terrain-provider-tianditu>-->
      <CesiumImagery
        :map-style="imageryConfig.mapStyle"
      />
      <vc-navigation
        :offset="navigationConfig.offset"
        :other-opts="navigationConfig.otherOpts"
      />
      <vc-ajax-bar />
      <CesiumHospitalPoint
        :show="layerControl.showHospital"
        :hospital-list="hospitalList"
      />
      <CesiumDistributionPoint
        :show="layerControl.showDistribution"
        :fire-center-weighted-list="distributionList"
        :distribution-sum="DistributionSum"
      />
      <CesiumTempPoint
        v-if="layerControl.tempRecuePoint"
        :location="startInfo"
      />
      <div v-if="Object.keys(cesium).length > 0&&layerControl.showRescueRoute">
        <div
          v-for="(rescueRoadInfo,index) in rescueRoadInfoList"
          :key="index"
        >
          <CesiumPathPlaning
            :cesium="cesium"
            :start="rescueRoadInfo.start"
            :end="rescueRoadInfo.end"
            :time="rescueTime"
            :travel-way="rescueRoadInfo.travelWay"
            :position="rescueRoadInfo.position"
            :model-info="rescueRoadInfo.modelInfo"
            :road-info="rescueRoadInfo.roadInfo"
          />-
        </div>
      </div>
    </vc-viewer>
  </el-row>
</template>

<script>
import  {getAllNearHospitalPositionByEarthquakeId,getHospitalByHospitalId,
getDetailEarthquakeInfoById,initEarthquakePositionInfo,getEarthquakeInfoById,
getNearFireCenterWeightByEarthquakeId,getNearestHospitalByPosition,searchRouteApi}  from "@/axios/api/cesium-api";
import DetailBox from "../components/detail-box.vue";
import EarthquakeSelect from "../components/earthquake-select.vue";
import AddEarthquake from "../components/add-earthquake.vue";
import EstimateEarthquake from "../components/estimate-earthquake.vue";
import ImgDisplay from "@/components/image-display.vue";
import SeismicZones from "@/components/seismic-zones.vue";
import Predict from "@/components/predict.vue";
import CesiumTileset from "@/components/cesium/cesium-tileset.vue";
import CesiumGeojson from "@/components/cesium/cesium-geojson.vue";
import CesiumMeasurements from "@/components/cesium/cesium-measurements.vue";
import CesiumEarthquakePoint from "@/components/cesium/cesium-earthquake-point.vue";
import CesiumEarthquakeIntensity from "@/components/cesium/cesium-earthquake-intensity.vue";
import CesiumImagery from "@/components/cesium/cesium-imagery.vue";
import CesiumHospitalPoint from "@/components/cesium/cesium-hospital-point.vue";
import CesiumDistributionPoint from "@/components/cesium/cesium-distribution-point.vue";
import {myMessage} from "@/assets/js/utils";
import CesiumPathPlaning from "@/components/cesium/cesium-path-planing.vue";
import CesiumTempPoint from "@/components/cesium/cesium-temp-point.vue";
export default {
  name: 'Cesium',
  components: {
    CesiumTempPoint,
    CesiumPathPlaning,
    CesiumDistributionPoint,
    CesiumHospitalPoint,
    CesiumImagery,
    CesiumEarthquakeIntensity,
    CesiumEarthquakePoint,
    CesiumMeasurements,
    CesiumGeojson,
    CesiumTileset,
    Predict,
    SeismicZones,
    ImgDisplay,
    DetailBox,
    EarthquakeSelect,
    AddEarthquake,
    EstimateEarthquake
  },
  data() {
    return {
      //详情传值
      detailInfo:{},
      //历史地震控制
      historyButtonVisible:false,
      //物资分配框控制
      suppliesVisible:false,
      //图片按钮控制
      imgButtonVisible:false,
      //物资分配
      DistrictSum:10,
      layerVisible:false,
      DistributionSum:1000,
      cesiumLoading:true,
      visibleRoad:false,
      Search:this.Search,
      Check:this.Check,
      hospitalList: [{
        "id": 61570,
        "lon": 114.455128,
        "lat": 23.927171
      }],
      distributionList:[{
        "fireId": 11627,
        "fireLon": 114.703487,
        "fireLat": 23.760898,
        "fireName": "河源市消防指挥中心",
        "fireAddress": "东华路永福西路",
        "fireCenterWeight": 0.20407603568016142
      }],
      //记录列表地震
      earthquakeInfoList:[],
      //earthquakeInfo
      earthquakePositionInfoList:[{
        earthquakeId:1,
        longitude:99.87,
        latitude:25.67,
        magnitude:6.4
      }],
      //当前地震
      selectedEarthquakeInfo:{
        "earthquakeId": 1474,
        "earthquakeName": "云南大理州漾濞县",
        "magnitude": 6.4,
        "highIntensity": 8.308250979049514,
        "longitude": 99.87,
        "latitude": 25.67,
        "depth": 8.0,
        "earthquakeTime": "2021-05-21 21:48:34",
        "intensityLineList": [
            {
                "longRadius": 4.831947699520125,
                "shortRadius": 2.1831727770881724,
                "angle": 0.6,
                "intensity": 8,
                "earthquakeId": "1474"
            }
        ],
    },
      //detailBox
      detailBox:{
        showDetail: false,
        detailClass: 0,
        detailIndex: 0,
        quickEarthquakeId:0,
        showButton: true
      },
      //viewer
      viewerConfig:{
        animation: false,
        timeline: false,
        baseLayerPicker: false,
        fullscreenButton: false,
        infoBox: false,
        showCredit: false,
        fullscreenElement: document.body,
      },
      //imagery-provider
      imageryConfig:{
        mapStyle:'img_w',
        options: [
          {value: 'img_c', label: '全球影像地图服务(经纬度)'},
          {value: 'img_w', label: '全球影像地图服务(墨卡托)'},
          {value: 'vec_c', label: '全球矢量地图服务(经纬度)'},
          {value: 'vec_w', label: '全球矢量地图服务(墨卡托)'},
          {value: 'ter_c', label: '全球地形晕渲服务(经纬度)'},
          {value: 'ter_w', label: '全球地形晕渲服务(墨卡托)'},
          {value: 'ibo_c', label: '全球境界(经纬度)'},
          {value: 'ibo_w', label: '全球境界(墨卡托)'}
        ],
      },
      //navigation
      navigationConfig:{
        offset: [10, 25],
        otherOpts: {
          offset: [0, 32],
          position: 'bottom-right'
        },
      },
      //layerControl
      layerControl:{
        visible:false,
        showIntensity: false,//更改
        showEpicenter: true,
        showHospital: false,
        showDistribution: false,
        showGeojson:true,
        showRescueRoute:false,
        tempRecuePoint:false, //是否已经选择救援点
      },
      chooseRecuePoint:false,//是否可以选择救援点
      startInfo:{
        longitude:100.246377,
        latitude:25.596945,
        height:0.0
      },
      rescueTime:{
        start:new Date('2024-08-03T12:00:00Z'),
        end:new Date('2024-08-03T12:01:40Z')
      },
      travelWay: 'driving',
      rescueRoadInfoList:[],
      cesium:{},
    }
  },
  computed:{
    judgeSelected:function () {
        //不可更改为===
      return this.detailBox.quickEarthquakeId !==this.selectedEarthquakeInfo.earthquakeId;
    }
  },
  watch: {
    detailBox:{
      handler(detailbox){
        this.imgButtonVisible = detailbox.quickEarthquakeId === 1474 && detailbox.detailClass === 1;
      },
      immediate:true,
      deep:true
    },
  },
  created() {
    this.getEarthquakeList();
  },
  mounted() {
    this.$refs.vcViewer.createPromise.then(({viewer }) => {
      viewer.scene.globe.depthTestAgainstTerrain = false;
    });
  },
  methods: {
      imgDisplayVisible(){
      this.$refs.img.ImgDisplayVisible = this.selectedEarthquakeInfo.earthquakeId === 1474;
    },
    closeIndex(val){
      this.detailBox.showDetail=false
      this.$refs.add.addEarthquakeVisible=false
      this.$refs.estimate.dialogVisible=false
      this.$refs.select.earthquakeSelectVisible=false
      this.$refs.SeismicZones.SeismicZonesVisible=false
      if(val==='predict')
        this.$refs.predict.addEarthquakeVisible=true
      if(val==='add')
        this.$refs.add.addEarthquakeVisible=true
      if(val==='estimate')
        this.$refs.estimate.dialogVisible=true
      if(val==='select')
        this.$refs.select.earthquakeSelectVisible=true
      if(val==='SeismicZones')
        this.$refs.SeismicZones.SeismicZonesVisible=true
      console.log(val)
    },
      reGetCalculateWeight(){
      this.$message.warning("请耐心等待，后台正在重新进行物资分配~")
      this.distributionList=[]
      this.getFireCenters();
    },
    //update earthquake list
    updateEarthquakePositionInfoList(list){
        this.earthquakePositionInfoList=list
        for(let i=0;i<list.length;i++){
            if(this.selectedEarthquakeInfo.earthquakeId===list[i].earthquakeId)
                return;
        }
        if(list.length===0) return;
        this.selectedEarthquakeInfo=list[0]
        this.getHospitals()
    },
    //get earthquake list
    getEarthquakeList(){
      let self=this;
      myMessage.elSuccess('正在查询地震数据,请稍后....')
          initEarthquakePositionInfo(8).then(response=>{
            self.earthquakePositionInfoList=response;
            self.getHospitals();
            self.cesiumLoading=false;
            // setTimeout(function (){
            //   self.cameraTo(self.selectedEarthquakeInfo.longitude,self.selectedEarthquakeInfo.latitude,100000)
            // },2000)
          })
    },
    cesiumReady(){
        //存储Cesium库便于其它组件使用
      this.cesium=Cesium
    },
    //change selected earthquake by index
    updateSelectedEarthquake(earthquakeId){
      console.log(earthquakeId)
      const self=this
      // this.imageryConfig.mapStyle="img_w";
      getEarthquakeInfoById(earthquakeId).then(response=>{
        self.selectedEarthquakeInfo=response
        self.getHospitals();
        self.detailBox.showDetail=false;
      })
    },
    //change location
    cameraTo(lat,lon,height){
      this.imageryConfig.mapStyle="img_w";
      let viewer=this.$refs.vcViewer.getCesiumObject();
      viewer.camera.flyTo(
          {
            destination : Cesium.Cartesian3.fromDegrees(lat,lon,height),
            orientation : {
              heading : Cesium.Math.toRadians(0.0),
              pitch : Cesium.Math.toRadians(-90.0),
              roll : 0.0
            }
          }
      )
    },
    //event when mouse pick an entity or a position
    pickEvt(e){
      if(!e) {
          console.log("!e")
          return
      }
      this.layerControl.visible=false
      try{
        // console.log('pickEvt',e)
        if(e._id==='__Vc__Pick__Location__')
        {
          if(this.chooseRecuePoint)
          {
            let cartographic = Cesium.Cartographic.fromCartesian(e._position._value);
            this.startInfo.longitude = Cesium.Math.toDegrees(cartographic.longitude);
            this.startInfo.latitude = Cesium.Math.toDegrees(cartographic.latitude);
            this.startInfo.height=Cesium.Math.toDegrees(cartographic.height)
            this.layerControl.tempRecuePoint=true
            // this.chooseRecuePoint=false
          }
          else
          {
            this.visibleRoad = false;
          }
        }
        let kind=e.id.split("_")[0]
        let index=parseInt(e.id.split("_")[1])
        if(kind==='epicenter')
        {
          const self=this
          getDetailEarthquakeInfoById(index).then(response=>{
          self.detailInfo=response
          self.historyButtonVisible=true
          self.detailBox.showButton=true
          self.detailBox.showDetail=true
          self.detailBox.detailClass=1
          self.detailBox.detailIndex=index
          self.detailBox.quickEarthquakeId=index
         })
        }
        else if(kind==='hospital')
        {
          const self=this
          getHospitalByHospitalId({'hospitalId':index}).then(response=>{
          self.detailInfo=response
          self.historyButtonVisible=false
          self.detailBox.showButton=false
          self.detailBox.showDetail=true
          self.detailBox.detailClass=2
          self.detailBox.detailIndex=index
          self.detailBox.quickEarthquakeId=index
        })
        }
        else if(kind==='fireCenter')
        {
          this.historyButtonVisible=false
          index=parseInt(e.id.split("_")[1])
          this.detailBox.showButton=false
          this.detailBox.showDetail=true
          this.detailBox.detailClass=3
          this.detailBox.detailIndex=index
          this.detailInfo=[
          {
            key:'物资数量',
            value:this.detailBox.detailIndex,
          }]
        }
        else if(kind==='intensity')
        {
            index=parseInt(e.id.split("_")[1])
            this.detailBox.detailIndex=index
          this.detailInfo=[
          {
            key:'烈度',
            value:this.selectedEarthquakeInfo.intensityLineList[this.detailBox.detailIndex].intensity+'(选中区域外圈等烈度线)',
          },
          {
            key:'长轴半径',
            value:this.selectedEarthquakeInfo.intensityLineList[this.detailBox.detailIndex].longRadius+'km',
          },
          {
            key:'短轴半径',
            value:this.selectedEarthquakeInfo.intensityLineList[this.detailBox.detailIndex].shortRadius+'km',
          }
         ]
          this.historyButtonVisible=false
          this.detailBox.showButton=false
          this.detailBox.showDetail=true
          this.detailBox.detailClass=4
        }
        else
        {
          this.detailBox.showDetail=false
        }
      }
      catch (err) {
        this.detailBox.showDetail=false
      }
    },
    onViewerReady(cesiumInstance) {
    },
    getHospitals(){
      let self = this;
      getAllNearHospitalPositionByEarthquakeId({earthquakeId:this.selectedEarthquakeInfo.earthquakeId}).then(res=>{
        self.hospitalList = res.data
      });
    },
    getFireCenters(){
      // hyc
      this.distributionList=[];
      let self = this;
      getNearFireCenterWeightByEarthquakeId(this.selectedEarthquakeInfo.earthquakeId,this.DistrictSum).then(res=>{
        self.distributionList=res.data
        self.layerControl.visible=false
        self.layerControl.showDistribution=true
        myMessage.elSuccess('物资分配计算完成')
      })
      .catch(()=>{
        myMessage.elError('物资分配计算失败')
      });
    },
    stopPositionRoad(){
      this.chooseRecuePoint=false
      this.layerControl.showRescueRoute=false;
      this.rescueRoadInfoList=[]
      myMessage.elError("结束路径规划,如想要开启路径规划功能，请重新选点");

    },
    selectPositionRoad(){
      this.chooseRecuePoint=true
      myMessage.elSuccess("现在可以开始选取救援点啦~");
    },
    getPositionRoad() {
      if (!(this.chooseRecuePoint&&this.layerControl.tempRecuePoint)) {
        myMessage.elError("您还没有选取点，请点击屏幕进行选点")
        return;
      }
      this.chooseRecuePoint=false
      this.layerControl.tempRecuePoint=false
      this.layerControl.showRescueRoute=true
      let viewer=this.$refs.vcViewer.getCesiumObject();
      let playTime = 10;
      let startTime = viewer.clock.currentTime
      let endTime = Cesium.JulianDate.addSeconds(startTime,playTime,new Cesium.JulianDate());
      this.rescueTime.start=Cesium.JulianDate.toDate(startTime)
      this.rescueTime.end=Cesium.JulianDate.toDate(endTime)
      viewer.clock.currentTime = startTime;
      viewer.clock.multiplier = 1;
      viewer.clock.shouldAnimate = true;
      viewer.clock.stopTime = endTime;
      myMessage.elSuccess("开始路径规划！")
      this.layerControl.showHospital=true
      const self=this
      getNearestHospitalByPosition(this.startInfo.longitude,this.startInfo.latitude)
        .then((res1) => {
          self.layerControl.showRescueRoute=true
          // 对象深度拷贝，Json序列化
          searchRouteApi(res1,JSON.parse(JSON.stringify(self.startInfo)),self.travelWay)
              .then((res2)=>{
                console.log(res2)
                self.rescueRoadInfoList.push(res2)
              }
          )
        });

    }
  }
}
</script>

<style scoped>
.toolbar {
  position: absolute;
  left: 1%;
  top: 1%;
  /*min-width: 185px;*/
  z-index: 100;
  color: #fff!important;
  background-color: rgba(0,0,0,.2);
}

.toolbar-item{
  margin: 5px;
}

.viewer{
  width:100%;
  height:100vh;
}
</style>
